package Collision
{
	import flash.display.Sprite;
	import flash.geom.Point;

	public class MyObj
	{
		public var p1:Point=new Point();
		public var p2:Point=new Point();
		public var p3:Point=new Point();
		public var p4:Point=new Point();
		public var rotation:Number,w:int,h:int;
		public var obj:Sprite;
		public var cos:Number;
		public var sin:Number;
		public var offset:Point=new Point();
		public function MyObj(obj:Sprite){
			this.obj=obj;
			this.w=obj.width;
			this.h=obj.height;
			this.update();
		}
		public function update():void{
			this.rotation=obj.rotation*Math.PI/180;
			cos=Math.cos(rotation);
			sin=Math.sin(rotation);
			p1.x=obj.x+cos*w/2+sin*h/2;
			p1.y=obj.y+sin*w/2-cos*h/2;
			p2.x=obj.x+cos*w/2-sin*h/2;
			p2.y=obj.y+sin*w/2+cos*h/2;
			p3.x=obj.x-cos*w/2+sin*h/2;
			p3.y=obj.y-sin*w/2-cos*h/2;
			p4.x=obj.x-cos*w/2-sin*h/2;
			p4.y=obj.y-sin*w/2+cos*h/2;
		}
		private function overlay(x1:Number,x2:Number,xx1:Number,xx2:Number):Boolean{//проверяет наложение двух отрезков (x1,x2) и (xx1,xx2)
			//по неравенству треугольника
			//возвращает истину если накладываются
			return (Math.abs(x1-x2)+Math.abs(xx1-xx2))>Math.abs(Math.max(x1,x2,xx1,xx2)-Math.min(x1,x2,xx1,xx2));
		}
		private function overlay2(x1:Number,x2:Number,xx1:Number,xx2:Number):Number{//проверяет наложение двух отрезков (x1,x2) и (xx1,xx2)
			var over:Number=(Math.abs(x1-x2)+Math.abs(xx1-xx2))-Math.abs(Math.max(x1,x2,xx1,xx2)-Math.min(x1,x2,xx1,xx2));
			return over;
		}
		private function sign(x:Number):Number{
			if (x>=0) return 1;
			return -1;
		}
		public function hit2(obj:MyObj):Boolean{
			update();
			//1)проверяем пересечение ортогональных проекций OY OX
			offset.x=0;
			offset.y=0;
			var ofx:Number=overlay2(Math.min(p1.x,p2.x,p3.x,p4.x),Math.max(p1.x,p2.x,p3.x,p4.x),Math.max(obj.p1.x,obj.p2.x,obj.p3.x,obj.p4.x),Math.min(obj.p1.x,obj.p2.x,obj.p3.x,obj.p4.x));
			if (ofx<0){
				//если не перекрылись то не надо дальше смотреть проекции
				return false;
			}
			var ofy:Number=overlay2(Math.min(p1.y,p2.y,p3.y,p4.y),Math.max(p1.y,p2.y,p3.y,p4.y),Math.max(obj.p1.y,obj.p2.y,obj.p3.y,obj.p4.y),Math.min(obj.p1.y,obj.p2.y,obj.p3.y,obj.p4.y))
			if (ofy<0){
				//если не перекрылись то не надо дальше смотреть проекции
				return false;
			}
			//2)если проекции накладываются то смотрим далее, учитывая углы поворота 
			var tan:Number=Math.tan(rotation);
			//сначала на ось OX
			var p1x:Number=tan*p1.y+p1.x;
			var p2x:Number=tan*p2.y+p2.x;
			var p3x:Number=tan*p3.y+p3.x;
			var p4x:Number=tan*p4.y+p4.x;
			
			var op1x:Number=tan*obj.p1.y+obj.p1.x;
			var op2x:Number=tan*obj.p2.y+obj.p2.x;
			var op3x:Number=tan*obj.p3.y+obj.p3.x;
			var op4x:Number=tan*obj.p4.y+obj.p4.x;
			var of1:Number=overlay2(Math.max(p1x,p2x,p3x,p4x),Math.min(p1x,p2x,p3x,p4x),Math.max(op1x,op2x,op3x,op4x),Math.min(op1x,op2x,op3x,op4x));
			if (of1<0){
				return false;
			}
			
			//на ось OY
			var p1y:Number=-tan*p1.x+p1.y;
			var p2y:Number=-tan*p2.x+p2.y;
			var p3y:Number=-tan*p3.x+p3.y;
			var p4y:Number=-tan*p4.x+p4.y;
			
			var op1y:Number=-tan*obj.p1.x+obj.p1.y;
			var op2y:Number=-tan*obj.p2.x+obj.p2.y;
			var op3y:Number=-tan*obj.p3.x+obj.p3.y;
			var op4y:Number=-tan*obj.p4.x+obj.p4.y;
			var of2:Number=overlay2(Math.max(p1y,p2y,p3y,p4y),Math.min(p1y,p2y,p3y,p4y),Math.max(op1y,op2y,op3y,op4y),Math.min(op1y,op2y,op3y,op4y));
			if (of2<0){
				return false;
			}
			//3)теперь наоборот другой прямоугольник накладывает проекции
			var otan:Number=Math.tan(obj.rotation);
			p1x=otan*p1.y+p1.x;
			p2x=otan*p2.y+p2.x;
			p3x=otan*p3.y+p3.x;
			p4x=otan*p4.y+p4.x;
			
			op1x=otan*obj.p1.y+obj.p1.x;
			op2x=otan*obj.p2.y+obj.p2.x;
			op3x=otan*obj.p3.y+obj.p3.x;
			op4x=otan*obj.p4.y+obj.p4.x;
			var of3:Number=overlay2(Math.max(p1x,p2x,p3x,p4x),Math.min(p1x,p2x,p3x,p4x),Math.max(op1x,op2x,op3x,op4x),Math.min(op1x,op2x,op3x,op4x));
			if (of3<0){
				return false;
			}
			
			//на ось OY
			p1y=-otan*p1.x+p1.y;
			p2y=-otan*p2.x+p2.y;
			p3y=-otan*p3.x+p3.y;
			p4y=-otan*p4.x+p4.y;
			
			op1y=-otan*obj.p1.x+obj.p1.y;
			op2y=-otan*obj.p2.x+obj.p2.y;
			op3y=-otan*obj.p3.x+obj.p3.y;
			op4y=-otan*obj.p4.x+obj.p4.y;
			var of4:Number=overlay2(Math.max(p1y,p2y,p3y,p4y),Math.min(p1y,p2y,p3y,p4y),Math.max(op1y,op2y,op3y,op4y),Math.min(op1y,op2y,op3y,op4y));
			if (of4<0){
				return false;
			}
			
			var o:Number=Math.min(ofx,of1,of2,of3,of4);
			offset.x=o*Math.abs(cos)*sign(-this.obj.x+obj.obj.x);
			offset.y=o*Math.abs(sin)*sign(-this.obj.y+obj.obj.y);
			return true;
		}
		public function hitTest(obj:MyObj):Boolean{
			update();//обновляем координаты
			//1)проверяем пересечение ортогональных проекций OY OX
			if (!overlay(Math.min(p1.x,p2.x,p3.x,p4.x),Math.max(p1.x,p2.x,p3.x,p4.x),Math.max(obj.p1.x,obj.p2.x,obj.p3.x,obj.p4.x),Math.min(obj.p1.x,obj.p2.x,obj.p3.x,obj.p4.x))){
				//если перекрылись то не надо дальше смотреть проекции
				return false;
			}
			if (!overlay(Math.min(p1.y,p2.y,p3.y,p4.y),Math.max(p1.y,p2.y,p3.y,p4.y),Math.max(obj.p1.y,obj.p2.y,obj.p3.y,obj.p4.y),Math.min(obj.p1.y,obj.p2.y,obj.p3.y,obj.p4.y))){
				//если перекрылись то не надо дальше смотреть проекции
				return false;
			}
			//2)если проекции накладываются то смотрим далее, учитывая углы поворота 
			var tan:Number=Math.tan(rotation);
			//сначала на ось OX
			var p1x:Number=tan*p1.y+p1.x;
			var p2x:Number=tan*p2.y+p2.x;
			var p3x:Number=tan*p3.y+p3.x;
			var p4x:Number=tan*p4.y+p4.x;
			
			var op1x:Number=tan*obj.p1.y+obj.p1.x;
			var op2x:Number=tan*obj.p2.y+obj.p2.x;
			var op3x:Number=tan*obj.p3.y+obj.p3.x;
			var op4x:Number=tan*obj.p4.y+obj.p4.x;
			
			if (!overlay(Math.max(p1x,p2x,p3x,p4x),Math.min(p1x,p2x,p3x,p4x),Math.max(op1x,op2x,op3x,op4x),Math.min(op1x,op2x,op3x,op4x))){
				return false;
			}
			
			//на ось OY
			var p1y:Number=-tan*p1.x+p1.y;
			var p2y:Number=-tan*p2.x+p2.y;
			var p3y:Number=-tan*p3.x+p3.y;
			var p4y:Number=-tan*p4.x+p4.y;
			
			var op1y:Number=-tan*obj.p1.x+obj.p1.y;
			var op2y:Number=-tan*obj.p2.x+obj.p2.y;
			var op3y:Number=-tan*obj.p3.x+obj.p3.y;
			var op4y:Number=-tan*obj.p4.x+obj.p4.y;
			if (!overlay(Math.max(p1y,p2y,p3y,p4y),Math.min(p1y,p2y,p3y,p4y),Math.max(op1y,op2y,op3y,op4y),Math.min(op1y,op2y,op3y,op4y))){
				return false;
			}
			//3)теперь наоборот другой прямоугольник накладывает проекции
			var otan:Number=Math.tan(obj.rotation);
			p1x=otan*p1.y+p1.x;
			p2x=otan*p2.y+p2.x;
			p3x=otan*p3.y+p3.x;
			p4x=otan*p4.y+p4.x;
			
			op1x=otan*obj.p1.y+obj.p1.x;
			op2x=otan*obj.p2.y+obj.p2.x;
			op3x=otan*obj.p3.y+obj.p3.x;
			op4x=otan*obj.p4.y+obj.p4.x;
			
			if (!overlay(Math.max(p1x,p2x,p3x,p4x),Math.min(p1x,p2x,p3x,p4x),Math.max(op1x,op2x,op3x,op4x),Math.min(op1x,op2x,op3x,op4x))){
				return false;
			}
			
			//на ось OY
			p1y=-otan*p1.x+p1.y;
			p2y=-otan*p2.x+p2.y;
			p3y=-otan*p3.x+p3.y;
			p4y=-otan*p4.x+p4.y;
			
			op1y=-otan*obj.p1.x+obj.p1.y;
			op2y=-otan*obj.p2.x+obj.p2.y;
			op3y=-otan*obj.p3.x+obj.p3.y;
			op4y=-otan*obj.p4.x+obj.p4.y;
			if (!overlay(Math.max(p1y,p2y,p3y,p4y),Math.min(p1y,p2y,p3y,p4y),Math.max(op1y,op2y,op3y,op4y),Math.min(op1y,op2y,op3y,op4y))){
				return false;
			}
			return true;
		}
	}
}